package com.gzc.just.play.last.war.sceneserver.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import jakarta.persistence.*;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 玩家实体类
 * 
 * 对应数据库表：players
 * 作为Phase 4.3数据库持久化集成的一部分
 */
@Entity
@Table(name = "players", indexes = {
    @Index(name = "idx_username", columnList = "username"),
    @Index(name = "idx_level", columnList = "level"),
    @Index(name = "idx_create_time", columnList = "create_time")
})
@EntityListeners(AuditingEntityListener.class)
public class Player {
    
    // 构造函数
    public Player() {
        // 默认构造函数
        this.isOnline = false;
        this.isBanned = false;
        this.loginCount = 0;
    }
    
    public Player(String username, String passwordHash, String salt, String nickname) {
        this();
        this.username = username;
        this.passwordHash = passwordHash;
        this.salt = salt;
        this.nickname = nickname;
    }
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "player_id")
    private Long playerId;
    
    @Column(name = "username", nullable = false, unique = true, length = 50)
    private String username;
    
    @Column(name = "password_hash", nullable = false)
    @JsonIgnore
    private String passwordHash;
    
    @Column(name = "salt", nullable = false, length = 32)
    @JsonIgnore
    private String salt;
    
    @Column(name = "nickname", nullable = false, length = 50)
    private String nickname;
    
    @Column(name = "level", nullable = false)
    private Integer level = 1;
    
    @Column(name = "experience", nullable = false)
    private Long experience = 0L;
    
    @Column(name = "vip_level", nullable = false)
    private Integer vipLevel = 0;
    
    @Column(name = "avatar_url", length = 255)
    private String avatarUrl;
    
    @Column(name = "signature", length = 200)
    private String signature;
    
    @Column(name = "login_count", nullable = false)
    private Integer loginCount = 0;
    
    @Column(name = "last_login_time")
    private LocalDateTime lastLoginTime;
    
    @Column(name = "last_logout_time")
    private LocalDateTime lastLogoutTime;
    
    @CreatedDate
    @Column(name = "create_time", nullable = false, updatable = false)
    private LocalDateTime createTime;
    
    @LastModifiedDate
    @Column(name = "update_time", nullable = false)
    private LocalDateTime updateTime;
    
    @Column(name = "is_online", nullable = false)
    private Boolean isOnline = false;
    
    @Column(name = "is_banned", nullable = false)
    private Boolean isBanned = false;
    
    @Column(name = "ban_reason", length = 200)
    private String banReason;
    
    @Column(name = "ban_end_time")
    private LocalDateTime banEndTime;
    
    // 关联实体
    @OneToMany(mappedBy = "player", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<PlayerAttribute> attributes;
    
    @OneToMany(mappedBy = "player", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<PlayerInventory> inventory;
    
    @OneToMany(mappedBy = "player", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<PlayerFriend> friends;
    
    @OneToMany(mappedBy = "player", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<PlayerAchievement> achievements;
    
    @OneToMany(mappedBy = "player", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    @JsonIgnore
    private List<BattleRecord> battleRecords;
    
    // Getter和Setter方法
    public Long getPlayerId() {
        return playerId;
    }
    
    public void setPlayerId(Long playerId) {
        this.playerId = playerId;
    }
    
    public String getUsername() {
        return username;
    }
    
    public void setUsername(String username) {
        this.username = username;
    }
    
    public String getPasswordHash() {
        return passwordHash;
    }
    
    public void setPasswordHash(String passwordHash) {
        this.passwordHash = passwordHash;
    }
    
    public String getSalt() {
        return salt;
    }
    
    public void setSalt(String salt) {
        this.salt = salt;
    }
    
    public String getNickname() {
        return nickname;
    }
    
    public void setNickname(String nickname) {
        this.nickname = nickname;
    }
    
    public Integer getLevel() {
        return level;
    }
    
    public void setLevel(Integer level) {
        this.level = level;
    }
    
    public Long getExperience() {
        return experience;
    }
    
    public void setExperience(Long experience) {
        this.experience = experience;
    }
    
    public Integer getVipLevel() {
        return vipLevel;
    }
    
    public void setVipLevel(Integer vipLevel) {
        this.vipLevel = vipLevel;
    }
    
    public String getAvatarUrl() {
        return avatarUrl;
    }
    
    public void setAvatarUrl(String avatarUrl) {
        this.avatarUrl = avatarUrl;
    }
    
    public String getSignature() {
        return signature;
    }
    
    public void setSignature(String signature) {
        this.signature = signature;
    }
    
    public Integer getLoginCount() {
        return loginCount;
    }
    
    public void setLoginCount(Integer loginCount) {
        this.loginCount = loginCount;
    }
    
    public LocalDateTime getLastLoginTime() {
        return lastLoginTime;
    }
    
    public void setLastLoginTime(LocalDateTime lastLoginTime) {
        this.lastLoginTime = lastLoginTime;
    }
    
    public LocalDateTime getLastLogoutTime() {
        return lastLogoutTime;
    }
    
    public void setLastLogoutTime(LocalDateTime lastLogoutTime) {
        this.lastLogoutTime = lastLogoutTime;
    }
    
    public LocalDateTime getCreateTime() {
        return createTime;
    }
    
    public void setCreateTime(LocalDateTime createTime) {
        this.createTime = createTime;
    }
    
    public LocalDateTime getUpdateTime() {
        return updateTime;
    }
    
    public void setUpdateTime(LocalDateTime updateTime) {
        this.updateTime = updateTime;
    }
    
    public Boolean getIsOnline() {
        return isOnline;
    }
    
    public void setIsOnline(boolean isOnline) {
        this.isOnline = isOnline;
    }
    
    public Boolean getIsBanned() {
        return isBanned;
    }
    
    public void setIsBanned(Boolean isBanned) {
        this.isBanned = isBanned;
    }
    
    public String getBanReason() {
        return banReason;
    }
    
    public void setBanReason(String banReason) {
        this.banReason = banReason;
    }
    
    public LocalDateTime getBanEndTime() {
        return banEndTime;
    }
    
    public void setBanEndTime(LocalDateTime banEndTime) {
        this.banEndTime = banEndTime;
    }
    
    /**
     * 封禁玩家
     */
    public void ban(String reason, LocalDateTime endTime) {
        this.isBanned = true;
        this.banReason = reason;
        if (endTime != null) {
            this.banEndTime = endTime;
        }
    }
    
    /**
     * 解除封禁
     */
    public void unban() {
        this.isBanned = false;
        this.banReason = null;
        this.banEndTime = null;
    }
    
    /**
     * 检查是否被永久封禁
     */
    public boolean isPermanentlyBanned() {
        return isBanned && banEndTime == null;
    }
    
    /**
     * 检查是否被封禁（包括临时和永久）
     */
    public boolean isCurrentlyBanned() {
        if (!isBanned) {
            return false;
        }
        if (banEndTime == null) {
            return true; // 永久封禁
        }
        return LocalDateTime.now().isBefore(banEndTime);
    }
    
    /**
     * PlayerService中使用的封禁方法
     */
    public void banPlayer(String reason, LocalDateTime endTime) {
        this.isBanned = true;
        this.banReason = reason;
        if (endTime != null) {
            this.banEndTime = endTime;
        }
    }
    
    /**
     * 增加经验值
     */
    public void addExperience(long amount) {
        if (amount > 0) {
            this.experience += amount;
            
            // 简单的升级逻辑：每1000经验升1级
            int newLevel = Math.min(100, 1 + (int)(this.experience / 1000));
            if (newLevel > this.level) {
                this.level = newLevel;
            }
        }
    }
    
    /**
     * 检查是否可以升级
     */
    public boolean canLevelUp() {
        return this.level < 100 && this.experience >= this.level * 1000;
    }
    
    /**
     * 等级到指定级别
     */
    public void levelUpTo(int targetLevel) {
        while (this.level < targetLevel && this.level < 100) {
            this.addExperience((this.level + 1) * 1000);
        }
    }
    
    /**
     * 增加登录次数
     */
    public void incrementLoginCount() {
        this.loginCount++;
    }
    
    @Override
    public int hashCode() {
        return playerId.hashCode();
    }
    
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        
        Player player = (Player) o;
        
        return playerId.equals(player.getPlayerId());
    }
    
    @Override
    public String toString() {
        return new StringBuilder()
            .append("Player{id=").append(playerId)
            .append(", username='").append(username).append('\'')
            .append("', nickname='").append(nickname).append('\'')
            .append("', level=").append(level)
            .append(", experience=").append(experience)
            .append(", vipLevel=").append(vipLevel)
            .append(", avatarUrl='").append(avatarUrl).append('\'')
            .append(", signature='").append(signature).append('\'')
            .append(", loginCount=").append(loginCount)
            .append(", lastLoginTime=").append(lastLoginTime)
            .append(", lastLogoutTime=").append(lastLogoutTime)
            .append(", createTime=").append(createTime)
            .append(", updateTime=").append(updateTime)
            .append(", isOnline=").append(isOnline)
            .append(", isBanned=").append(isBanned)
            .append(", banReason='").append(banReason).append('\'')
            .append(", banEndTime=").append(banEndTime)
            .append('}')
            .toString();
    }
}